#include <stdio.h>
#include <stdlib.h>

#include "Tree.h"
#ifndef TREE_UTEST


#define IF_FAIL(X) if(X){printf("FAIL IN %s TEST, IN LINE %d\n",#X,__LINE__); return 1;}
typedef struct Person
{
    int age;
    char name[30];
}Person;

int PersonLess(void* _a, void* _b)
{
    return ((Person*)_a)->age < ((Person*)_b)->age;
}

int main()
{
    Tree* tree = TreeNew(PersonLess);
    TreeIter it;
    TreeIter it1;
    TreeIter it2;
    TreeIter it3;
    TreeIter it4;
    TreeIter it5;
    Person p1 = {33, "avi"};
    Person p2 = {44, "boby"};
    Person p3 = {11, "coco"};
    Person p4 = {5, "dado"};
    Person p5 = {22, "shoko"};
    Person ptest;

    /*  do rand ages    */
    IF_FAIL(!TreeIsEmpty(tree))     /*  Check tree is empty */

    it1  = TreeInsert(tree, &p1);
    IF_FAIL(TreeIsEmpty(tree))      /*  Check that now tree isn't empty */
    it2 = TreeInsert(tree, &p2);
    it4 = TreeInsert(tree, &p4);
    it3 = TreeInsert(tree, &p3);

    IF_FAIL(TreeGetData(it1) != &p1)                    /*  Check that iterator are corect, and check GetData                   */
    IF_FAIL(TreeBegin(tree) != it4)                     /*  Check that begin points to the beginning                            */

    ptest.age = 5;
    IF_FAIL(TreeFind(tree, &ptest) != it4)              /*  Check TreeFind return the right iterator                            */
    ptest.age = 3;                                      /*  Put not exist value                                                 */
    IF_FAIL(TreeFind(tree, &ptest) != TreeEnd(tree))    /*  Check that end iterator return                                      */
    IF_FAIL(!TreeIsEqual(TreeBegin(tree), it4))         /*  Chek TreeEqual work                                                 */
    IF_FAIL(!TreeIsEqual(TreeNext(it2), TreeEnd(tree)))
    IF_FAIL(!TreeIsEqual(TreeNext(it4), it3))
    IF_FAIL(!TreeIsEqual(TreeNext(it1), it2))

    IF_FAIL(!TreeIsEqual(TreePrev(it2), it1))
    IF_FAIL(!TreeIsEqual(TreePrev(it3), TreeBegin(tree)))
    IF_FAIL(!TreeIsEqual(TreePrev(it1), it3))
    IF_FAIL(!TreeIsEqual(TreePrev(TreeEnd(tree)), it2))

    it5 = TreeInsert(tree, &p5);

    for(it = TreeBegin(tree); !TreeIsEqual(it, TreeEnd(tree)); it = TreeNext(it))
    {
        printf("The age of %s is: %d\n", ((Person*)TreeGetData(it))->name, ((Person*)TreeGetData(it))->age);
    }

    puts("");
    it = TreeNext(TreeBegin(tree));
    IF_FAIL(it != TreeRemove(tree, TreeBegin(tree)));       /*  Check we get the next after remove  */
    ptest.age = 5;
    IF_FAIL(!TreeIsEqual(TreeFind(tree, &ptest), TreeEnd(tree)))    /*  Check that the lowest data removed  */

    TreeRemove(tree, TreeBegin(tree));
    TreeRemove(tree, TreeBegin(tree));

    TreeRemove(tree, TreeBegin(tree));

    TreeRemove(tree, TreeBegin(tree));

    IF_FAIL(!TreeIsEmpty(tree))

    for(it = TreeBegin(tree); !TreeIsEqual(it, TreeEnd(tree)); it = TreeNext(it))
    {
        printf("The age of %s is: %d\n", ((Person*)TreeGetData(it))->name, ((Person*)TreeGetData(it))->age);
    }

    TreeDel(tree);

    return 0;
}


#endif
